package net.shenru.os.task;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import net.shenru.base.ConstConfig;
import net.shenru.os.task.WorkerAsyncTask.WorkerTaskListener;
import net.shenru.os.utlis.SrLog;

/**
 * 任务管理器
 */
public class TaskManager implements Observer, WorkerTaskListener {
	private static final String TAG = TaskManager.class.getSimpleName();

	private TaskQueue taskQueue;
	private static final int MAX_TASK_COUNT = ConstConfig.MAX_TASK_COUNT;
	private int taskCount;

	public TaskManager() {
		taskQueue = new TaskQueue();
		taskQueue.regTaskQueueListener(this);
		taskCount = 0;
	}

	public void addTask(ITask task) {
		SrLog.i(TAG, "添加一个任务到任务管理器");
		if(task.getStatue() != TaskStatue.Prepare){
			throw new IllegalArgumentException("任务以运行");
		}
		taskQueue.add(task);
	}

	public void removeTask(ITask task) {
		taskQueue.remove(task);
	}

	public ArrayList<ITask> getAllTask() {
		return taskQueue.getAllTask();
	}

	/**
	 * 运行任务
	 */
	private void run(ITask task) {
		task.setStatue(TaskStatue.Runing);
		WorkerAsyncTask asyncTask = new WorkerAsyncTask(this);
		asyncTask.execute(task);
	}

	/**
	 * 检测队列
	 */
	private void checkTask() {
		ITask task = taskQueue.getTask();
		while (taskCount < MAX_TASK_COUNT && task != null) {
			if(task.getStatue() != TaskStatue.Prepare){
				throw new IllegalArgumentException("任务不是准备状态");
			}
			run(task);
			task = taskQueue.getTask();
		}
	}

	// ----------------------------------------
	// 队列任务监听
	@Override
	public void update(Observable ovaervable, Object obj) {
		ITask task = (ITask) obj;
		if (task != null && task.getStatue() == TaskStatue.Prepare) {
			run(task);
		}
		checkTask();
	}

	// ------------------------------------------------------------------
	// 运行任务监听
	@Override
	public ITask doInBackground(ITask task) {
		return null;
	}

	@Override
	public void onPreExecute() {
		// ++Object 与 Object++的区别
		++taskCount;
	}

	@Override
	public void onPostExecute(ITask result) {
		taskCount--;
		// 当任务执行完毕，检测任务是否执行出行错误。通过错误策略在次执行
		taskQueue.remove(result);
		checkTask();
	}
}
